#include "frontend/parser.h"
#include <algorithm>
#include <iostream>
#include <set>

namespace mspc {

Parser::Parser(TokenContainer tokens)
    : tokens_(std::move(tokens)) {}

std::unique_ptr<File> Parser::parse() { return parse_file(); }

std::unique_ptr<File> Parser::parse_file() {
    auto file = MakeUnique<File>();
    file->filename = tokens_.filename();

    try {
        while (!tokens_.is_at_end()) {
            if (match(TokenType::KW_SYNTAX)) {
                file->syntax_version = parse_syntax();
            } else if (match(TokenType::KW_PACKAGE)) {
                file->package_name = parse_package();
            } else if (match(TokenType::KW_IMPORT)) {
                file->imports.push_back(parse_import());
            } else if (match(TokenType::KW_STRUCT)) {
                file->structs.push_back(parse_struct());
            } else if (match(TokenType::KW_MESSAGE)) {
                file->messages.push_back(parse_message());
            } else if (match(TokenType::KW_ENUM)) {
                file->enums.push_back(parse_enum());
            } else {
                throw_error("Expected struct, message, enum, import, or package declaration");
                break;
            }
        }
    } catch (const ParserError& e) {
        errors_.push_back(tokens_.format_error(e.what()));
    }

    return file;
}

std::string Parser::parse_syntax() {
    consume(TokenType::EQUAL, "Expected '=' after 'syntax'");
    auto str_token =
        consume(TokenType::STRING_LITERAL, "Expected string literal for syntax version");
    consume(TokenType::SEMICOLON, "Expected ';' after syntax declaration");

    // 移除引号
    std::string value = str_token.value;
    if (value.size() >= 2 && value.front() == '"' && value.back() == '"') {
        return value.substr(1, value.size() - 2);
    }
    return value;
}

std::string Parser::parse_package() {
    std::vector<std::string> parts;

    // 第一个部分必须是标识符
    auto first_part = consume(TokenType::IDENTIFIER, "Expected package name");
    parts.push_back(first_part.value);

    // 读取后续的点号和标识符
    while (match(TokenType::DOT)) {
        auto next_part = consume(TokenType::IDENTIFIER, "Expected package part after dot");
        parts.push_back(next_part.value);
    }

    consume(TokenType::SEMICOLON, "Expected ';' after package name");

    // 验证包名格式
    std::string package_name;
    for (size_t i = 0; i < parts.size(); i++) {
        // 验证每个部分
        if (!is_valid_identifier(parts[i])) {
            throw ParserError("Invalid package part: " + parts[i]);
        }
        if (i > 0) package_name += ".";
        package_name += parts[i];
    }

    return package_name;
}
std::unique_ptr<ImportStmt> Parser::parse_import() {
    auto import = MakeUnique<ImportStmt>();
    import->line = tokens_.peek().line;
    import->column = tokens_.peek().column;

    auto str_token = consume(TokenType::STRING_LITERAL, "Expected import filename");
    import->filename = str_token.value;

    // 移除引号
    if (import->filename.size() >= 2 && import->filename.front() == '"' &&
        import->filename.back() == '"') {
        import->filename = import->filename.substr(1, import->filename.size() - 2);
    }

    consume(TokenType::SEMICOLON, "Expected ';' after import");
    return import;
}

std::unique_ptr<StructDef> Parser::parse_struct() {
    auto struct_def = MakeUnique<StructDef>();
    struct_def->line = tokens_.previous().line;
    struct_def->column = tokens_.previous().column;

    struct_def->name = consume(TokenType::IDENTIFIER, "Expected struct name").value;
    consume(TokenType::LBRACE, "Expected '{' after struct name");

    while (!check(TokenType::RBRACE) && !tokens_.is_at_end()) {
        struct_def->fields.push_back(parse_field());
    }

    consume(TokenType::RBRACE, "Expected '}' to end struct definition");
    return struct_def;
}

std::unique_ptr<MessageDef> Parser::parse_message() {
    auto message = MakeUnique<MessageDef>();
    message->line = tokens_.previous().line;
    message->column = tokens_.previous().column;

    message->name = consume(TokenType::IDENTIFIER, "Expected message name").value;
    consume(TokenType::LBRACE, "Expected '{' after message name");

    // 消息必须包含id字段
    if (match(TokenType::KW_ID)) {
        consume(TokenType::EQUAL, "Expected '=' after 'id'");
        message->id = parse_number();
        consume(TokenType::SEMICOLON, "Expected ';' after message id");
    } else {
        throw_error("Message must have an 'id' field");
    }

    while (!check(TokenType::RBRACE) && !tokens_.is_at_end()) {
        if (check(TokenType::KW_MESSAGE)) {
            tokens_.advance(); // 跳过message关键字
            message->nested_messages.push_back(parse_message());
        } else if (check(TokenType::KW_ENUM)) {
            tokens_.advance(); // 跳过enum关键字
            message->nested_enums.push_back(parse_enum());
        } else if (check(TokenType::KW_STRUCT)) {
            tokens_.advance(); // 跳过struct关键字
            message->nested_structs.push_back(parse_struct());
        } else {
            message->fields.push_back(parse_field());
        }
    }

    consume(TokenType::RBRACE, "Expected '}' to end message definition");
    return message;
}

std::unique_ptr<EnumDef> Parser::parse_enum() {
    auto enum_def = MakeUnique<EnumDef>();
    enum_def->line = tokens_.previous().line;
    enum_def->column = tokens_.previous().column;

    enum_def->name = consume(TokenType::IDENTIFIER, "Expected enum name").value;
    consume(TokenType::LBRACE, "Expected '{' after enum name");

    while (!check(TokenType::RBRACE) && !tokens_.is_at_end()) {
        enum_def->values.push_back(parse_enum_value());
    }

    consume(TokenType::RBRACE, "Expected '}' to end enum definition");
    return enum_def;
}

std::unique_ptr<EnumValue> Parser::parse_enum_value() {
    auto value = MakeUnique<EnumValue>();
    value->line = tokens_.peek().line;
    value->column = tokens_.peek().column;

    value->name = consume(TokenType::IDENTIFIER, "Expected enum value name").value;
    consume(TokenType::EQUAL, "Expected '=' after enum value name");

    auto num_token = consume(TokenType::NUMBER, "Expected enum value number");
    try {
        value->value = std::stoi(num_token.value);
    } catch (const std::exception&) {
        throw_error(num_token, "Invalid enum value number: " + num_token.value);
        value->value = 0;
    }

    // 解析可选的选项
    if (match(TokenType::LBRACKET)) {
        auto options = parse_options();
        value->options = std::move(options);
        consume(TokenType::RBRACKET, "Expected ']' after options");
    }

    consume(TokenType::SEMICOLON, "Expected ';' after enum value");
    return value;
}

std::unique_ptr<FieldDef> Parser::parse_field() {
    auto field = MakeUnique<FieldDef>();
    field->line = tokens_.peek().line;
    field->column = tokens_.peek().column;

    // 解析字段规则 (repeated)
    if (match(TokenType::KW_REPEATED)) {
        field->rule = "repeated";
    }

    // 解析字段类型
    field->type = parse_type();

    // 解析字段名称
    field->name = consume(TokenType::IDENTIFIER, "Expected field name").value;

    // 解析字段编号
    consume(TokenType::EQUAL, "Expected '=' after field name");
    field->number = parse_number();

    // 解析可选的默认值
    if (match(TokenType::COLON)) {
        field->default_value = parse_default_value();
    }

    // 解析可选的字段选项
    /*
    if (match(TokenType::LBRACKET)) {
        field->options = parse_options();
        consume(TokenType::RBRACKET, "Expected ']' after field options");
    }
    */
    consume(TokenType::SEMICOLON, "Expected ';' after field definition");
    return field;
}

std::unique_ptr<OptionDef> Parser::parse_option() {
    auto option = MakeUnique<OptionDef>();
    option->line = tokens_.peek().line;
    option->column = tokens_.peek().column;

    option->name = consume(TokenType::IDENTIFIER, "Expected option name").value;
    consume(TokenType::EQUAL, "Expected '=' after option name");

    if (check(TokenType::IDENTIFIER) || check(TokenType::NUMBER)) {
        option->value = tokens_.advance().value;
    } else if (check(TokenType::STRING_LITERAL)) {
        option->value = parse_string_literal();
    } else {
        throw_error("Expected option value");
        option->value = "";
    }

    return option;
}

// 工具方法实现
std::string Parser::parse_type() {
    if (check(TokenType::IDENTIFIER)) {
        return tokens_.advance().value;
    }

    // 检查基础类型
    static const auto type_tokens = init_type_words_table2();

    if (type_tokens.count(tokens_.peek().type)) {
        return tokens_.advance().value;
    }

    throw_error("Expected type name (unknown type name)");
    return "unknown";
}

uint32_t Parser::parse_number() {
    auto token = consume(TokenType::NUMBER, "Expected number");
    try {
        return std::stoul(token.value);
    } catch (const std::exception&) {
        throw_error(token, "Invalid number: " + token.value);
        return 0;
    }
}

std::string Parser::parse_string_literal() {
    auto token = consume(TokenType::STRING_LITERAL, "Expected string literal");
    return token.value;
}

std::string Parser::parse_default_value() {
    if (check(TokenType::NUMBER) || check(TokenType::IDENTIFIER)) {
        return tokens_.advance().value;
    } else if (check(TokenType::STRING_LITERAL)) {
        return parse_string_literal();
    } else {
        throw_error("Expected default value");
        return "";
    }
}

std::vector<std::unique_ptr<OptionDef>> Parser::parse_options() {
    std::vector<std::unique_ptr<OptionDef>> options;

    do {
        options.push_back(parse_option());
    } while (match(TokenType::COMMA));

    return options;
}

bool Parser::check(TokenType type) const {
    if (tokens_.is_at_end()) return false;
    return tokens_.peek().type == type;
}

bool Parser::match(TokenType type) {
    if (check(type)) {
        tokens_.advance();
        return true;
    }
    return false;
}

Token Parser::consume(TokenType type, const std::string& message) {
    if (check(type)) return tokens_.advance();

    const auto& token = tokens_.peek();
    throw ParserError(message + ", but found " + token.value + " at " + tokens_.filename() + ":" +
                      std::to_string(token.line) + ":" + std::to_string(token.column));
}

bool Parser::is_valid_identifier(const std::string& ident) {
    if (ident.empty() || (!std::isalpha(ident[0]) && ident[0] != '_')) {
        return false;
    }

    for (char c : ident) {
        if (!std::isalnum(c) && c != '_') {
            return false;
        }
    }

    return true;
}

void Parser::throw_error(const Token& token, const std::string& message) {
    throw ParserError(tokens_.filename() + ": " + std::to_string(token.line) + ":" +
                      std::to_string(token.column) + ": " + message);
}

void Parser::throw_error(const std::string& message) {
    throw ParserError(tokens_.format_error(message));
}

} // namespace mspc